home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Main.bin / Menu.java < prev    next >
Text File  |  1998-09-22  |  14KB  |  455 lines

  1. /*
  2.  * @(#)Menu.java    1.41 98/08/21
  3.  *
  4.  * Copyright 1995-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  * 
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14. package java.awt;
  15.  
  16. import java.util.Vector;
  17. import java.util.Enumeration;
  18. import java.awt.peer.MenuPeer;
  19. import java.awt.event.KeyEvent;
  20.  
  21. /**
  22.  * A <code>Menu</code> object is a pull-down menu component 
  23.  * that is deployed from a menu bar. 
  24.  * <p>
  25.  * A menu can optionally be a <i>tear-off</i> menu. A tear-off menu 
  26.  * can be opened and dragged away from its parent menu bar or menu. 
  27.  * It remains on the screen after the mouse button has been released. 
  28.  * The mechanism for tearing off a menu is platform dependent, since 
  29.  * the look and feel of the tear-off menu is determined by its peer.
  30.  * On platforms that do not support tear-off menus, the tear-off
  31.  * property is ignored.
  32.  * <p>
  33.  * Each item in a menu must belong to the <code>MenuItem</code> 
  34.  * class. It can be an instance of <code>MenuItem</code>, a submenu 
  35.  * (an instance of <code>Menu</code>), or a check box (an instance of 
  36.  * <code>CheckboxMenuItem</code>).
  37.  *
  38.  * @version 1.41, 08/21/98
  39.  * @author Sami Shaio
  40.  * @see     java.awt.MenuItem
  41.  * @see     java.awt.CheckboxMenuItem
  42.  * @since   JDK1.0
  43.  */
  44. public class Menu extends MenuItem implements MenuContainer {
  45.     Vector        items = new Vector();
  46.     boolean        tearOff;
  47.     boolean        isHelpMenu;
  48.  
  49.     private static final String base = "menu";
  50.     private static int nameCounter = 0;
  51.  
  52.     /*
  53.      * JDK 1.1 serialVersionUID 
  54.      */
  55.      private static final long serialVersionUID = -8809584163345499784L;
  56.  
  57.     /** 
  58.      * Constructs a new menu with an empty label. This menu is not
  59.      * a tear-off menu.
  60.      * @since      JDK1.1
  61.      */
  62.     public Menu() {
  63.     this("", false);
  64.     }
  65.  
  66.     /** 
  67.      * Constructs a new menu with the specified label. This menu is not
  68.      * a tear-off menu.
  69.      * @param       label the menu's label in the menu bar, or in 
  70.      *                   another menu of which this menu is a submenu.
  71.      * @since       JDK1.0
  72.      */
  73.     public Menu(String label) {
  74.     this(label, false);
  75.     }
  76.  
  77.     /** 
  78.      * Constructs a new menu with the specified label. If the 
  79.      * value of <code>tearOff</code> is <code>true</code>,
  80.      * the menu can be torn off.
  81.      * <p>
  82.      * Tear-off functionality may not be supported by all 
  83.      * implementations of AWT.  If a particular implementation doesn't 
  84.      * support tear-off menus, this value is silently ignored.
  85.      * @param       label the menu's label in the menu bar, or in 
  86.      *                   another menu of which this menu is a submenu.
  87.      * @param       tearOff   if <code>true</code>, the menu 
  88.      *                   is a tear-off menu.
  89.      * @since       JDK1.0.
  90.      */
  91.     public Menu(String label, boolean tearOff) {
  92.     super(label);
  93.     this.tearOff = tearOff;
  94.     }
  95.  
  96.     /**
  97.      * Construct a name for this MenuComponent.  Called by getName() when
  98.      * the name is null.
  99.      */
  100.     String constructComponentName() {
  101.     return base + nameCounter++;
  102.     }
  103.  
  104.     /**
  105.      * Creates the menu's peer.  The peer allows us to modify the 
  106.      * appearance of the menu without changing its functionality.
  107.      */
  108.     public void addNotify() {
  109.         synchronized (getTreeLock()) {
  110.         if (peer == null) {
  111.             peer = Toolkit.getDefaultToolkit().createMenu(this);
  112.         }
  113.         int nitems = getItemCount();
  114.         for (int i = 0 ; i < nitems ; i++) {
  115.             MenuItem mi = getItem(i);
  116.             mi.parent = this;
  117.             mi.addNotify();
  118.         }
  119.         }
  120.     }
  121.  
  122.     /**
  123.      * Removes the menu's peer.  The peer allows us to modify the appearance
  124.      * of the menu without changing its functionality.
  125.      */
  126.     public void removeNotify() {
  127.         synchronized (getTreeLock()) {
  128.         int nitems = getItemCount();
  129.         for (int i = 0 ; i < nitems ; i++) {
  130.             getItem(i).removeNotify();
  131.         }
  132.         super.removeNotify();
  133.         }
  134.     }
  135.  
  136.     /**
  137.      * Indicates whether this menu is a tear-off menu.  
  138.      * <p>
  139.      * Tear-off functionality may not be supported by all 
  140.      * implementations of AWT.  If a particular implementation doesn't 
  141.      * support tear-off menus, this value is silently ignored.
  142.      * @return      <code>true</code> if this is a tear-off menu; 
  143.      *                         <code>false</code> otherwise.
  144.      * @since       JDK1.0
  145.      */
  146.     public boolean isTearOff() {
  147.     return tearOff;
  148.     }
  149.  
  150.     /** 
  151.       * Get the number of items in this menu.
  152.       * @return     the number of items in this menu.
  153.       * @since      JDK1.1
  154.       */
  155.     public int getItemCount() {
  156.     return countItems();
  157.     }
  158.  
  159.     /** 
  160.      * @deprecated As of JDK version 1.1,
  161.      * replaced by <code>getItemCount()</code>.
  162.      */
  163.     public int countItems() {
  164.     return items.size();
  165.     }
  166.  
  167.     /**
  168.      * Gets the item located at the specified index of this menu.
  169.      * @param     index the position of the item to be returned.
  170.      * @return    the item located at the specified index.
  171.      * @since     JDK1.0
  172.      */
  173.     public MenuItem getItem(int index) {
  174.     return (MenuItem)items.elementAt(index);
  175.     }
  176.  
  177.     /**
  178.      * Adds the specified menu item to this menu. If the 
  179.      * menu item has been part of another menu, remove it  
  180.      * from that menu. 
  181.      * @param       mi   the menu item to be added.
  182.      * @return      the menu item added.
  183.      * @see         java.awt.Menu#insert(java.lang.String, int)
  184.      * @see         java.awt.Menu#insert(java.awt.MenuItem, int)
  185.      * @since       JDK1.0
  186.      */
  187.     public MenuItem add(MenuItem mi) {
  188.         synchronized (getTreeLock()) {
  189.         if (mi.parent != null) {
  190.             mi.parent.remove(mi);
  191.         }
  192.         items.addElement(mi);
  193.         mi.parent = this;
  194.             MenuPeer peer = (MenuPeer)this.peer;
  195.         if (peer != null) {
  196.             mi.addNotify();
  197.             peer.addItem(mi);
  198.         }
  199.         return mi;
  200.         }
  201.     }
  202.  
  203.     /**
  204.      * Adds an item with the specified label to this menu. 
  205.      * @param       label   the text on the item.
  206.      * @see         java.awt.Menu#insert(java.lang.String, int)
  207.      * @see         java.awt.Menu#insert(java.awt.MenuItem, int)
  208.      * @since       JDK1.0
  209.      */
  210.     public void add(String label) {
  211.     add(new MenuItem(label));
  212.     }
  213.  
  214.     /**
  215.      * Inserts a menu item into this menu 
  216.      * at the specified position.
  217.      * @param         menuitem  the menu item to be inserted.
  218.      * @param         index     the position at which the menu  
  219.      *                          item should be inserted.
  220.      * @see           java.awt.Menu#add(java.lang.String)
  221.      * @see           java.awt.Menu#add(java.awt.MenuItem)
  222.      * @exception     IllegalArgumentException if the value of
  223.      *                    <code>index</code> is less than zero.
  224.      * @since         JDK1.1
  225.      */
  226.  
  227.     public void insert(MenuItem menuitem, int index) {
  228.         synchronized(getTreeLock()) {
  229.         if (index < 0) {
  230.             throw new IllegalArgumentException("index less than zero.");
  231.         }
  232.  
  233.             int nitems = getItemCount();
  234.         Vector tempItems = new Vector();
  235.  
  236.         /* Remove the item at index, nitems-index times 
  237.            storing them in a temporary vector in the
  238.            order they appear on the menu.
  239.          */
  240.         for (int i = index ; i < nitems; i++) {
  241.             tempItems.addElement(getItem(index));
  242.             remove(index);
  243.         }
  244.  
  245.         add(menuitem);
  246.  
  247.         /* Add the removed items back to the menu, they are
  248.            already in the correct order in the temp vector.
  249.          */
  250.         for (int i = 0; i < tempItems.size()  ; i++) {
  251.             add((MenuItem)tempItems.elementAt(i));
  252.         }
  253.         }
  254.     }
  255.  
  256.     /**
  257.      * Inserts a menu item with the specified label into this menu 
  258.      * at the specified position.
  259.      * @param       label the text on the item.
  260.      * @param       index the position at which the menu item 
  261.      *                      should be inserted.
  262.      * @see         java.awt.Menu#add(java.lang.String)
  263.      * @see         java.awt.Menu#add(java.awt.MenuItem)
  264.      * @since       JDK1.1
  265.      */
  266.  
  267.     public void insert(String label, int index) {
  268.         insert(new MenuItem(label), index);
  269.     }
  270.       
  271.     /**
  272.      * Adds a separator line, or a hypen, to the menu at the current position.
  273.      * @see         java.awt.Menu#insertSeparator(int)
  274.      * @since       JDK1.0
  275.      */
  276.     public void addSeparator() {
  277.     add("-");
  278.     }
  279.  
  280.     /**
  281.      * Inserts a separator at the specified position.
  282.      * @param       index the position at which the 
  283.      *                       menu separator should be inserted.
  284.      * @exception   IllegalArgumentException if the value of 
  285.      *                       <code>index</code> is less than 0.
  286.      * @see         java.awt.Menu#addSeparator
  287.      * @since       JDK1.1
  288.      */
  289.  
  290.     public void insertSeparator(int index) {
  291.         synchronized(getTreeLock()) {
  292.         if (index < 0) {
  293.             throw new IllegalArgumentException("index less than zero.");
  294.         }
  295.  
  296.             int nitems = getItemCount();
  297.         Vector tempItems = new Vector();
  298.  
  299.         /* Remove the item at index, nitems-index times 
  300.            storing them in a temporary vector in the
  301.            order they appear on the menu.
  302.            */
  303.         for (int i = index ; i < nitems; i++) {
  304.             tempItems.addElement(getItem(index));
  305.             remove(index);
  306.         }
  307.  
  308.         addSeparator();
  309.  
  310.         /* Add the removed items back to the menu, they are
  311.            already in the correct order in the temp vector.
  312.            */
  313.         for (int i = 0; i < tempItems.size()  ; i++) {
  314.             add((MenuItem)tempItems.elementAt(i));
  315.         }
  316.         }
  317.     }
  318.  
  319.     /**
  320.      * Removes the menu item at the specified index from this menu.
  321.      * @param       index the position of the item to be removed. 
  322.      * @since       JDK1.0 
  323.      */
  324.     public void remove(int index) {
  325.         synchronized (getTreeLock()) {
  326.         MenuItem mi = getItem(index);
  327.         items.removeElementAt(index);
  328.             MenuPeer peer = (MenuPeer)this.peer;
  329.         if (peer != null) {
  330.             mi.removeNotify();
  331.             mi.parent = null;
  332.             peer.delItem(index);
  333.         }
  334.         }
  335.     }
  336.  
  337.     /**
  338.      * Removes the specified menu item from this menu.
  339.      * @param       item the item to be removed from the menu
  340.      * @since       JDK1.0
  341.      */
  342.     public void remove(MenuComponent item) {
  343.         synchronized(getTreeLock()) {
  344.         int index = items.indexOf(item);
  345.         if (index >= 0) {
  346.              remove(index);
  347.         }
  348.         }
  349.     }
  350.  
  351.     /**
  352.      * Removes all items from this menu.
  353.      * @since       JDK1.0.
  354.      */
  355.     public void removeAll() {
  356.       synchronized(getTreeLock()) {
  357.         int nitems = getItemCount();
  358.     for (int i = 0 ; i < nitems ; i++) {
  359.         remove(0);
  360.     }
  361.       }
  362.     }
  363.  
  364.     /*
  365.      * Post an ActionEvent to the target of the MenuPeer 
  366.      * associated with the specified keyboard event (on 
  367.      * keydown).  Returns true if there is an associated 
  368.      * keyboard event.
  369.      */
  370.     boolean handleShortcut(KeyEvent e) {
  371.         int nitems = getItemCount();
  372.         for (int i = 0 ; i < nitems ; i++) {
  373.             MenuItem mi = getItem(i);
  374.             if (mi.handleShortcut(e)) {
  375.                 return true;
  376.             }
  377.         }
  378.         return false;
  379.     }
  380.  
  381.     MenuItem getShortcutMenuItem(MenuShortcut s) {
  382.     int nitems = getItemCount();
  383.     for (int i = 0 ; i < nitems ; i++) {
  384.             MenuItem mi = getItem(i).getShortcutMenuItem(s);
  385.             if (mi != null) {
  386.                 return mi;
  387.             }
  388.     }
  389.         return null;
  390.     }
  391.  
  392.     synchronized Enumeration shortcuts() {
  393.         Vector shortcuts = new Vector();
  394.         int nitems = getItemCount();
  395.     for (int i = 0 ; i < nitems ; i++) {
  396.             MenuItem mi = getItem(i);
  397.             if (mi instanceof Menu) {
  398.                 Enumeration e = ((Menu)mi).shortcuts();
  399.                 while (e.hasMoreElements()) {
  400.                     shortcuts.addElement(e.nextElement());
  401.                 }
  402.             } else {
  403.                 MenuShortcut ms = mi.getShortcut();
  404.                 if (ms != null) {
  405.                     shortcuts.addElement(ms);
  406.                 }
  407.             }
  408.     }
  409.         return shortcuts.elements();
  410.     }
  411.  
  412.     void deleteShortcut(MenuShortcut s) {
  413.     int nitems = getItemCount();
  414.     for (int i = 0 ; i < nitems ; i++) {
  415.         getItem(i).deleteShortcut();
  416.     }
  417.     }
  418.  
  419.  
  420.     /* Serialization support.  A MenuContainer is responsible for
  421.      * restoring the parent fields of its children. 
  422.      */
  423.  
  424.     private int menuSerializedDataVersion = 1;
  425.  
  426.     private void writeObject(java.io.ObjectOutputStream s)
  427.       throws java.lang.ClassNotFoundException,
  428.          java.io.IOException 
  429.     {
  430.       s.defaultWriteObject();
  431.     }
  432.  
  433.     private void readObject(java.io.ObjectInputStream s)
  434.       throws java.lang.ClassNotFoundException,
  435.          java.io.IOException 
  436.     {
  437.       s.defaultReadObject();
  438.       for(int i = 0; i < items.size(); i++) {
  439.     MenuItem item = (MenuItem)items.elementAt(i);
  440.     item.parent = this;
  441.       }
  442.     }
  443.  
  444.     /**
  445.      * Gets the parameter string representing the state of this menu. 
  446.      * This string is useful for debugging.
  447.      * @since      JDK1.0nu.
  448.      */
  449.     public String paramString() {
  450.         String str = ",tearOff=" + tearOff+",isHelpMenu=" + isHelpMenu;
  451.         return super.paramString() + str;
  452.     }
  453. }
  454.  
  455.